/*
 * @Author: fubobo
 * @Date: 2025-08-06 14:16:07
 * @LastEditors: Please set LastEditors
 * @LastEditTime: 2025-08-07 17:19:47
 * @Description: ai绘画基类
 */

import { userUploadImages } from "@/api/common";
import { type ResOriginalImage } from "@/api/types/commonType";
// TODO: 基础类先不过多抽象，目前移动端只考虑工作流
abstract class BaseAInstance {
  // 公共参数
  protected params: IBaseAIParams;
  constructor(initialParams: Partial<IBaseAIParams> = {}) {
    //   设置默认参数
    this.params = {
      CLIP_stop_at_last_layers: 3,
      ...initialParams,
    };
  }

  abstract generate(): Promise<void>;

  /**
   * 公共方法获取图片宽高
   * @param {*} base64
   * @returns { width: number; height: number }
   */
  getImgSize = (base64: Base64URLString) => {
    return new Promise<{ width: number; height: number }>((resolve, reject) => {
      uni.getImageInfo({
        src: base64,
        success: (res) => {
          const { width, height } = res;
          resolve({ width, height });
        },
        fail: reject,
      });
    });
  };

  /**
   * @description: PC端继承方法
   * @param {object} wh
   * @param {boolean} isXL
   * @return {*}
   */
  getCalcOriginWh = <T extends { width: number; height: number }>(wh: T, isXL: boolean): T => {
    if (isXL) {
      const maxlen = Math.max(wh.width, wh.height);
      const minlen = Math.min(wh.width, wh.height);
      const minRate = 1024 / minlen; // 最小边放大到1024的比例
      const maxRate = 2048 / maxlen; // 最大边放大到2048的比例
      if (Math.floor(minRate * wh.width) > 2048 || Math.floor(minRate * wh.height) > 2048) {
        // 最小边得到比例计算长边大于2048
        // 用长边计算
        return {
          width: Math.floor(maxRate * wh.width),
          height: Math.floor(maxRate * wh.height),
        } as T;
      } else {
        // 用短边计算
        return {
          width: Math.floor(minRate * wh.width),
          height: Math.floor(minRate * wh.height),
        } as T;
      }
    } else {
      const maxlen = Math.max(wh.width, wh.height);
      const rate = 1024 / maxlen;
      return {
        width: Math.floor(rate * wh.width),
        height: Math.floor(rate * wh.height),
      } as T;
    }
  };

  /**
   * PC端继承方法
   * @param {CN模型名称} module
   * @param {模型参数} model
   * @param {*} weight
   * @param {图片去掉base64头部} input_image
   * @returns
   */
  CNArgbuilder = (module: string, model: string, weight = 1, input_image: Base64URLString) => {
    return {
      model: model,
      module: module,
      processor_res: 1024,
      trigg_symb: true,
      input_image: input_image,
      weight: weight,
      guidance_start: 0,
      guidance_end: 1,
      control_mode: "My prompt is more important",
      UUID: null, // 上传后得到UUID
    };
  };

  // 上传图片
  uploadImages = (base64: string) => {
    return new Promise<ResOriginalImage>(async (resolve, reject) => {
      try {
        const { data } = await userUploadImages([base64]);
        if (!data) return;
        resolve(data[0]);
      } catch (error) {
        reject(error);
      }
    });
  };

  removeBase64Head = (code64 = "") => {
    return code64 ? code64.split("base64,")[1] : null;
  };

  // TODO: 目前只处理了微信小程序 图转base64
  imageToBase64 = (src: string) => {
    return new Promise<string>(async (resolve, _reject) => {
      let base64 = "";
      // 处理 H5 平台
      // #ifdef H5
      //   base64 = await this.h5ImageToBase64(compressedPath);
      // #endif

      // 处理非 H5 平台（小程序/App）
      // #ifndef H5
      base64 = (await this.nonH5ImageToBase64(src)) as string;
      // #endif
      resolve(base64);
    });
  };

  // H5 转换方法
  h5ImageToBase64(file: Blob) {
    return new Promise((resolve) => {
      const reader = new FileReader();
      reader.onload = (e) => resolve(e.target?.result);
      reader.readAsDataURL(file);
    });
  }

  // 非 H5 转换方法
  nonH5ImageToBase64(filePath: string) {
    return new Promise<string | ArrayBuffer>((resolve, reject) => {
      uni.getImageInfo({
        src: filePath,
        success: (res) => {
          const fs = uni.getFileSystemManager();
          fs.readFile({
            filePath: res.path,
            encoding: "base64",
            success: (res) => {
              //   const base64Header = `data:${imageInfo.type};base64,`;
              resolve(res.data);
            },
            fail: reject,
          });
        },
        fail: reject,
      });
    });
  }
}

export default BaseAInstance;

// 基础参数接口
export interface IBaseAIParams {
  CLIP_stop_at_last_layers: number;
}
